package com.meeruu.sg.account.core.domain.component.thread;

import java.util.concurrent.*;

/**
 * @Auther: liwu
 * @Date: 2019/5/6 14:14
 * @Description:
 */
public class ThreadExecutorTemplate {


    ExecutorService executorService;

    /**
     * 固定线程
     */
    ThreadExecutorTemplate() {

        executorService = Executors.newSingleThreadExecutor();
    }

    /**
     * 指定线程
     */
    ThreadExecutorTemplate(int fixedPool) {

        executorService = Executors.newFixedThreadPool(fixedPool);

    }

    /**
     * 自己创建
     */
    ThreadExecutorTemplate(int corePoolSize, int maxPoolSize) {

        executorService = new ThreadPoolExecutor(corePoolSize, maxPoolSize,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());
    }

    /**
     * 自己定义队列大小,和拒绝策略
     */
    ThreadExecutorTemplate(int corePoolSize, int maxPoolSize, int queueSize) {

        executorService = new ThreadPoolExecutor(corePoolSize, maxPoolSize,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(queueSize), exeHandler);
    }


    /**
     * 拒绝策略
     * 当队列满、线程不足或是其他原因，可能导致的执行任务未被正常执行时的回调接口
     */
    private RejectedExecutionHandler exeHandler = (r, executor) -> {

        if (r instanceof ExecutorRunnable) {

            ((ExecutorRunnable) r).rejectedExecution();
        }
    };


    public void execute(ThreadBizInvoke threadBizInvoke) {

        execute(threadBizInvoke, null);
    }

    public void execute(final ThreadBizInvoke threadBizInvoke, ExecutionReject executionReject) {

        executorService.execute(new ExecutorRunnable(threadBizInvoke, executionReject));
    }

    public <V> V submit(final ThreadBizInvoke threadBizInvoke) {

        return (V) executorService.submit(() -> threadBizInvoke.invoke());
    }

}
